#ifndef _EASYLOG_H
#define _EASYLOG_H

#include "easylog_cfg.h"

#ifdef _EASYLOG

#include <stdint.h>

#define CSI_START                      "\033["
#define CSI_END                        "\033[0m"
/* output log front color */
#define F_BLACK                        "30;"
#define F_RED                          "31;"
#define F_GREEN                        "32;"
#define F_YELLOW                       "33;"
#define F_BLUE                         "34;"
#define F_MAGENTA                      "35;"
#define F_CYAN                         "36;"
#define F_WHITE                        "37;"
/* output log background color */
#define B_NULL
#define B_BLACK                        "40;"
#define B_RED                          "41;"
#define B_GREEN                        "42;"
#define B_YELLOW                       "43;"
#define B_BLUE                         "44;"
#define B_MAGENTA                      "45;"
#define B_CYAN                         "46;"
#define B_WHITE                        "47;"
/* output log fonts style */
#define S_BOLD                         "1m"
#define S_UNDERLINE                    "4m"
#define S_BLINK                        "5m"
#define S_NORMAL                       "22m"


/* output log's level */
#define ELOG_LVL_ASSERT                 0
#define ELOG_LVL_ERROR                  1
#define ELOG_LVL_WARN                   2
#define ELOG_LVL_DEBUG                  3
#define ELOG_LVL_INFO                   4
#define ELOG_LVL_VERBOSE                5

#define ELOG_COLOR_ASSERT               (F_MAGENTA B_NULL S_NORMAL)
#define ELOG_COLOR_ERROR                (F_RED B_NULL S_NORMAL)
#define ELOG_COLOR_WARN                 (F_YELLOW B_NULL S_NORMAL)
#define ELOG_COLOR_INFO                 (F_CYAN B_NULL S_NORMAL)
#define ELOG_COLOR_DEBUG                (F_GREEN B_NULL S_NORMAL)
#define ELOG_COLOR_VERBOSE              (F_BLUE B_NULL S_NORMAL)



#ifdef _EASYLOG_ASSERT
    #define _ASSERT(EXPR) \
    if((!EXPR)){\
        EASYLOG_ASSERT("ASSERT","(%s)has asser at %s:%ld.",#EXPR,__FUNCTION__,__LINE__);\
        while(1);\
    }
#else
    #define EASYLOG_ASSERT(EXPR) ((void) 0)
#endif

#if _EASYLOG_OUT_LEVEL >= ELOG_LVL_ASSERT
    #define EASYLOG_ASSERT(TAG,...)\
    do{eEasylogOutput(ELOG_LVL_ASSERT,TAG,NULL,NULL,0,##__VA_ARGS__);}while(0)
#else
    #define EASYLOG_ASSERT(TAG,...)
#endif

#if _EASYLOG_OUT_LEVEL >= ELOG_LVL_ERROR
    #define EASYLOG_ERROR(TAG,...)\
    do{eEasylogOutput(ELOG_LVL_ERROR,TAG,__FILE__,NULL,__LINE__,##__VA_ARGS__);}while(0)
#else
    #define EASYLOG_ERROR(TAG,...)
#endif

#if _EASYLOG_OUT_LEVEL >= ELOG_LVL_WARN
    #define EASYLOG_WARN(TAG,...)\
    do{eEasylogOutput(ELOG_LVL_WARN,TAG,NULL,NULL,0,##__VA_ARGS__);}while(0)
#else
    #define ESAYLOG_WARN(TAG,...)
#endif

#if _EASYLOG_OUT_LEVEL >= ELOG_LVL_DEBUG
    #define EASYLOG_DEBUG(TAG,...)\
    do{eEasylogOutput(ELOG_LVL_DEBUG,TAG,NULL,NULL,0,##__VA_ARGS__);}while(0)
#else
    #define EASYLOG_DEBUG(TAG,...)
#endif

#if _EASYLOG_OUT_LEVEL >= ELOG_LVL_INFO
    #define EASYLOG_INFO(TAG,...)\
    do{eEasylogOutput(ELOG_LVL_INFO,TAG,NULL,NULL,0,##__VA_ARGS__);}while(0)
#else
    #define EASYLOG_DEBUG(TAG,...)
#endif

#if _EASYLOG_OUT_LEVEL >= ELOG_LVL_VERBOSE
    #define EASYLOG_VERBOSE(TAG,...)\
    do{eEasylogOutput(ELOG_LVL_VERBOSE,TAG,NULL,NULL,0,##__VA_ARGS__);}while(0)
#else
    #define EASYLOG_DEBUG(TAG,...)
#endif

#ifdef _EASYLOG_NORMAL
    #define EASYLOG_NORMAL(...) eEasylogOutputNormal(__VA_ARGS__)
#else
    #define EASYLOG_NORMAL(...)
#endif

#ifdef _EASYLOG_HEX
    #define EASYLOG_HEX(TAG,date,size)\
    do{eEasylogHexOutput(ELOG_LVL_INFO,TAG,date,size);}while(0)
    #define EASYLOG_HEX_DUMP(name,width,buffer,size)  \
    do{eEasylogHexDump(name,width,buffer,size);}while(0)
#else
    #define EASYLOG_HEX(TAG,date,size)
    #define EASYLOG_HEX_DUMP(name,width,buffer,size)
#endif


typedef void (*eEasylogPut)(char *,uint32_t);
typedef uint32_t (*eEasylogTimer)(void);

#ifdef __cpulsplus
extern "C"{
#endif
extern void eEasylogLevelSet(uint8_t level);
extern void eEasylogOutput(uint8_t level,const char *tag,const char *file,const char *func,
                    const long line,const char *format,...);
extern void eEasylogHexOutput(uint8_t level,const char *tag,void *date,uint16_t size);
extern void eEasylogPutRegister(eEasylogPut put);
extern void eEasylogOutputNormal(const char *format,...);
extern void eEasylogHexDump(const char *name, uint8_t width, const void *buf, uint16_t size);
#ifdef _EASYLOG_TIME
extern void eEasylogTimerRegister(eEasylogTimer timer);
#endif

#ifdef __cplusplus
}
#endif

#endif

#endif
